/**
 * @(#)ConfigurationParameter.java
 *
 * @author Alan Salnikov
 * @author Mankin Yuen
 * @author William Clark
 * @version 1.00 2008/12/1
 */
package edg.acm;

import java.util.*;

/**
 * Provides a library to access the list of parameters and the attributes of a
 * specified parameter, such as the bounds, the type, and if it is required.
 */
public class ConfigurationParameter {

	static Map<String, ConfigurationParameter> paramList = new LinkedHashMap<String, ConfigurationParameter>();
	static {
		add(new ConfigurationParameter("doctor", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("nurse", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("external triage", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("internal triage", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("external clerk", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("internal clerk", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("bed", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("lab tech", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("ctscan tech", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("xray tech", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("ultrasound tech", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("rate", Integer.class, true, 1, 60));
		add(new ConfigurationParameter("runs", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("hours", Integer.class, true, 1, Integer.MAX_VALUE));
		add(new ConfigurationParameter("acuity1", Integer.class, true, 0, 100));
		add(new ConfigurationParameter("acuity2", Integer.class, true, 0, 100));
		add(new ConfigurationParameter("acuity3", Integer.class, true, 0, 100));
		add(new ConfigurationParameter("acuity4", Integer.class, true, 0, 100));
		add(new ConfigurationParameter("acuity5", Integer.class, true, 0, 100));
		add(new ConfigurationParameter("acuity6", Integer.class, true, 0, 100));
		add(new ConfigurationParameter("walkin", Integer.class, true, 0, 100));
	}

	static void add(ConfigurationParameter p) {
		paramList.put(p.getName(), p);
	}

	String name;
	Class<?> type;
	boolean required;
	Number min;
	Number max;

	/**
	 * private constructor for static creation... This whole construct may be
	 * better done as an enum.. Or for more dynamic models, not, and initialize
	 * models with a link back to the validating parameters
	 * 
	 * @param n
	 *            name of the parameter
	 * @param t
	 * @param r
	 * @param mn
	 * @param mx
	 */
	private ConfigurationParameter(String n, Class<?> t, boolean r, int mn, int mx) {
		name = n;
		type = t;
		required = r;
		min = mn;
		max = mx;
	}

	/**
	 * Retrieves the parameter specified by <tt>name</tt>
	 * 
	 * @param name
	 *            the name of the parameter
	 * @return the parameter
	 * @throws InvalidParameterException
	 *             if the name is not of a valid parameter
	 */
	public static ConfigurationParameter getParameter(String name) {
		ConfigurationParameter temp = paramList.get(name);
		if (temp == null)
			throw new InvalidParameterException();
		return temp;
	}

	/**
	 * 
	 * @return a list of all valid parameters
	 */
	public static List<ConfigurationParameter> getParameters() {
		return new ArrayList<ConfigurationParameter>(paramList.values());
	}

	/**
	 * 
	 * @return the name of the parameter
	 */
	public String getName() {
		return name;
	}

	/**
	 * 
	 * @return the {@link Class} of the parameter
	 */
	public Class<?> getType() {
		return type;
	}

	/**
	 * 
	 * @return whether the parameter is required
	 */
	public boolean isRequired() {
		return required;
	}

	/**
	 * 
	 * @return the minimum bound of the parameter
	 */
	public Number getMinimum() {
		return min;
	}

	/**
	 * 
	 * @return the maximum bound of the parameter
	 */
	public Number getMaximum() {
		return max;
	}
}